package logica.persistencia;

import java.util.List;

import logica.Diagrama;
import logica.Entidad;
import logica.IdExternoInexistenteException;
import logica.Jerarquia;
import logica.Relacion;

import org.jdom.Element;

import borrador.grafica.TransformadorAGraficable;

import vista.objetos.DiagramaGraficable;
import vista.objetos.EntidadGraficable;
import vista.objetos.EntidadTipoNoSoportadoException;
import vista.objetos.GraficableConEtiqueta;
import vista.objetos.JerarquiaGraficable;
import vista.objetos.RelacionGraficable;
import vista.objetos.RelacionTipoNoSoportadoException;
import vista.paneles.hojaDibujo.OrientacionHoja;
import xml.ConstantesXml;
import xml.XMLManager;

public class DiagramaGraficablePersistente {
	private DiagramaGraficable diagramaGraficable;
	private Diagrama diagrama;
	private Element elementoDiagrama;
	
	public DiagramaGraficablePersistente(DiagramaGraficable _diagramaGraficable) {
		diagramaGraficable = _diagramaGraficable;
		diagrama = _diagramaGraficable.getDiagrama();
	}
	
	public Element getElementoDiagrama() {
		return elementoDiagrama;
	}

	public void setElementoDiagrama(Element elementoDiagrama) {
		this.elementoDiagrama = elementoDiagrama;
	}
	
	public DiagramaGraficable getDiagramaGraficable(){
		return diagramaGraficable;
	}
	
	public void serializarDiagramaGraficoGenerico() {
		Element elementoDiagrama = new Element(ConstantesXml.ELEMENTO_DIAGRAMA);
		XMLManager.getInstance().agregarRaizGrafico(elementoDiagrama);
		
		this.setElementoDiagrama(elementoDiagrama);
		int identificador = XMLManager.getIdentificador(diagrama);
		String idDiagrama= String.valueOf(identificador);
		
		elementoDiagrama.setAttribute(ConstantesXml.ATRIBUTO_NOMBRE, diagrama.getNombre());
		elementoDiagrama.setAttribute(ConstantesXml.ATRIBUTO_ID_OBJETO, idDiagrama);
		
		Element objetos = new Element (ConstantesXml.ELEMENTO_GRAFICABLES);
		elementoDiagrama.addContent(objetos);
		
		List<GraficableConEtiqueta> graficables = diagramaGraficable.getGraficables();
	
		for (GraficableConEtiqueta graficable: graficables) {
			GraficableConEtiquetaPersistente objDiagrama = graficable.getGraficableConEtiquetaPersistente();
			objDiagrama.setElementoPadre(objetos);
			objDiagrama.serializar();
		}
		
		this.serializarConfiguracionHoja();
	}
	
	private void hidratarEntidadesGraficables(Element graficables) {
		@SuppressWarnings("unchecked")
		List<Element> elementosEntidadesGraficables = graficables.getChildren(ConstantesXml.ELEMENTO_ENTIDAD);
		
		for (Element elementoEntidadG : elementosEntidadesGraficables) {
			String idString = elementoEntidadG.getAttributeValue(ConstantesXml.ATRIBUTO_ID_OBJETO);
			Entidad entidad = (Entidad)XMLManager.getInstance().objtenerObjetoDiagramaConClave(idString);
			
			EntidadGraficable entidadGraficable;
			try {
				entidadGraficable = TransformadorAGraficable.getEntidadGraficable(entidad);
				
				//Hasheo el elemento para poder obtenerlo después a través del id
				
				String id = elementoEntidadG.getAttributeValue(ConstantesXml.ATRIBUTO_ID_OBJETO);
				
				XMLManager.getInstance().hashObjetoDiagramaRepConClave(id, entidadGraficable);
				
				
				EntidadGraficablePersistente entidadG = new EntidadGraficablePersistente(entidadGraficable);
				entidadG.setElementoGraficable(elementoEntidadG);
				entidadG.hidratar();
				diagramaGraficable.agregarGraficable(entidadGraficable); 
			} catch (EntidadTipoNoSoportadoException e) {
				e.printStackTrace();
			}
		}
	}
	
	private void hidratarRelacionesGraficables(Element graficables) {
		@SuppressWarnings("unchecked")
		List<Element> elementosRelacionesGraficables = graficables.getChildren(ConstantesXml.ELEMENTO_RELACION);
		
		for (Element elementoRelacionG : elementosRelacionesGraficables) {
			String idString = elementoRelacionG.getAttributeValue(ConstantesXml.ATRIBUTO_ID_OBJETO);
			Relacion relacion = (Relacion)XMLManager.getInstance().objtenerObjetoDiagramaConClave(idString);
			if (relacion != null) {
				RelacionGraficable relacionGraficable;
				try {
					relacionGraficable = TransformadorAGraficable.getRelacionGraficable(relacion);
					RelacionGraficablePersistente relacionG = new RelacionGraficablePersistente(relacionGraficable);
					relacionG.setElementoGraficable(elementoRelacionG);
					relacionG.hidratar();
					diagramaGraficable.agregarGraficable(relacionGraficable);
				} catch (RelacionTipoNoSoportadoException e) {
					e.printStackTrace();
				}
			}
		}
		
	}
	
	private void hidratarJerarquiasGraficables(Element graficables) {
		@SuppressWarnings("unchecked")
		List<Element> elementosJerarquiasGraficables = graficables.getChildren(ConstantesXml.ELEMENTO_JERARQUIA);
		
		for (Element elementoJerarquiaG : elementosJerarquiasGraficables) {
			String idString = elementoJerarquiaG.getAttributeValue(ConstantesXml.ATRIBUTO_ID_OBJETO);
			Jerarquia jerarquia = (Jerarquia)XMLManager.getInstance().objtenerObjetoDiagramaConClave(idString);
			if (jerarquia != null) {
				JerarquiaGraficable jerarquiaGraficable = TransformadorAGraficable.getJerarquiaGraficable(jerarquia);
				JerarquiaGraficablePersistente jerarquiaG = new JerarquiaGraficablePersistente(jerarquiaGraficable);
				jerarquiaG.setElementoGraficable(elementoJerarquiaG);
				jerarquiaG.hidratar();
				diagramaGraficable.agregarGraficable(jerarquiaGraficable);
			}
		}
		
	}
	public void hidratarDiagramaGraficoGenerico() {
		Element elementoDiagrama = XMLManager.getInstance().obtenerRaiz();
		this.setElementoDiagrama(elementoDiagrama);
		
		String idRef = elementoDiagrama.getAttributeValue(ConstantesXml.ATRIBUTO_ID_OBJETO);
		String idDiagrama= String.valueOf(idRef);
		Diagrama diagP = (Diagrama) XMLManager.getInstance().objtenerObjetoDiagramaConClave(idDiagrama);
		
		diagramaGraficable.setDiagrama(diagP);
	
		Element graficables = elementoDiagrama.getChild(ConstantesXml.ELEMENTO_GRAFICABLES);
	
		
		this.hidratarEntidadesGraficables(graficables);
		this.hidratarRelacionesGraficables(graficables);
		this.hidratarJerarquiasGraficables(graficables);
		this.hidratarConfiguracionHoja();
		this.hidratarIdentificadoresGraficos();
	}

	private void hidratarIdentificadoresGraficos() {
		for (GraficableConEtiqueta graf: diagramaGraficable.getGraficables())
			if (graf instanceof EntidadGraficable)
				try {
					EntidadGraficable entidadGraficable = (EntidadGraficable) graf;
					entidadGraficable.setReferenciasExternas(entidadGraficable.getDiagrama());
					entidadGraficable.crearIdentificadores();
				} catch (IdExternoInexistenteException e) {
					e.printStackTrace();
				}
	}

	public void serializarConfiguracionHoja (){
		String configHoja = diagramaGraficable.getOrientacion().name();
		if (configHoja != null)
			this.elementoDiagrama.setAttribute(ConstantesXml.CONFIGURACION_HOJA, configHoja);
	}
	public void hidratarConfiguracionHoja () {
		String configHoja = this.elementoDiagrama.getAttributeValue(ConstantesXml.CONFIGURACION_HOJA);
		if (configHoja != null) {
			OrientacionHoja orientacion = OrientacionHoja.valueOf(configHoja);
			diagramaGraficable.setOrientacion(orientacion);
		}
	}
	

	public void serializar() {
		this.serializarDiagramaGraficoGenerico();
	}

	public void hidratar() {
		this.hidratarDiagramaGraficoGenerico();
	}
}
